#pragma once

#include<iostream>
#include<functional>
#include<string>
#include<pthread.h>


template<class T>
using func_t =std::function<void(T&)>;


template<class T>
class Thread
{
public:
    Thread(const std::string&  pthreadName,func_t<T> fun,const T& data)
        :_tid(0),_pthreadName(pthreadName),_fun(fun),_isRunning(false),_data(data)
    {}


    static void *threadRountine(void * args)
    {
        Thread *ts=static_cast<Thread*>(args);
        
        ts->_fun(ts->_data);
        
        return nullptr;
    }
    bool Start()
    {
        int n=pthread_create(&_tid,NULL,threadRountine,this/* 为线程任务封装准备*/);
        if(n==0)
        {
            _isRunning=true;
            return true;
        }    
        else 
            return false;
    }


    bool Join()
    {
        if(!_isRunning)
            return false;
        
        int n=pthread_join(_tid,NULL);

        if(n==0)
        {
            _isRunning=false;
            return true;
        }
        return false;
  
   }

   bool IsRunning()
   {
    return _isRunning;
   }

   std::string  ThreadName()
   {
        return _pthreadName;
   }

    ~Thread()
    {}
private:
    pthread_t _tid;
    std::string _pthreadName;
    func_t<T> _fun;
    bool _isRunning;
    T _data;
};